<?php

/**
 * Holds class Mvc_Request
 *
 * @author Mark
 *
 * @package Library
 * @subpackage Mvc
 */

/**
 * Model view controller request object
 *
 * @author Mark
 * @author daan.timmer
 */
class Mvc_Request {

	/**
	 * Current action
	 * @var string $_action
	 */
	protected $_action;

	/**
	 * Current controller
	 * @var string $_controller
	 */
	protected $_controller;

	/**
	 * Current module
	 * @var string $_module
	 */
	protected $_module;

	/**
	 * Additional parameters
	 * @var array $_param
	 */
	protected $_param = array();

	/**
	 * Post Object
	 *
	 * @var Post $post
	 */
	public $post;

	/**
	 * Constructor
	 *
	 * @return void
	 */
	public function __construct() {
		//
		$this->post = new Post();
	}

	/**
	 * Returns all additional parameters
	 *
	 * @return array
	 */
	public function getAllParams() {
		return $this->_param;
	}

	/**
	 * Returns action
	 *
	 * @return string
	 */
	public function getAction() {
		return $this->_action;
	}

	/**
	 * Returns controller
	 *
	 * @return string
	 */
	public function getController() {
		return $this->_controller;
	}

	/**
	 * Returns cookie information
	 *
	 * @param string $key
	 * @throws Exception
	 * @return array|string
	 */
	public function getCookie($key) {
		if(!isset($key)) {
			return $_COOKIE;
		}

		if(isset($_COOKIE[$key])) {
			return $_COOKIE[$key];
		}
		throw new Exception('Cookie variable ' . $key . ' does not exist');
	}

	/**
	 * Returns file information
	 *
	 * @param string $key
	 * @throws Exception
	 * @return array|string
	 */
	public function getFile($key) {
		if(!isset($key)) {
			return $_FILES;
		}

		if(isset($_FILES[$key])) {
			return $_FILES[$key];
		}
		throw new Exception('File variable ' . $key . ' does not exist');
	}

	/**
	 * Returns module
	 *
	 * @return string
	 */
	public function getModule() {
		return $this->_module;
	}

	/**
	 * Returns parameter
	 *
	 * @param string $key
	 * @throws Exception
	 * @return string
	 */
	public function getParam($key) {
		if(isset($this->_param[$key])) {
			return $this->_param[$key];
		}
		throw new Exception('Parameter ' . $key . ' does not exist');
	}

	public function hasParam($key){
		return key_exists($key, $this->_param);
		//return isset($this->_param[$key]);
	}

	public function __get($key){
		return $this->getParam($key);
	}

	/**
	 * Returns post information
	 *
	 * @param string $key (optional)
	 * @throws Exception
	 * @return array|string
	 */
	public function getPost($key = null) {
		if(!isset($key)) {
			return $_POST;
		}

		if($this->hasPost($key)) {
			return $_POST[$key];
		}
		throw new Exception('Post variable ' . $key . ' does not exist');
	}

	/**
	 * Returns if $key exists in $_POST
	 *
	 * @param string $key
	 * @return boolean
	 */
	public function hasPost($key){
		return isset($_POST[$key]);
	}

	/**
	* Returns if array of $keys exists in $_POST
	*
	* @param array $keys
	* @return boolean
	*/
	public function hasPostArray($keys = array()){
		foreach($keys as $key){
			if(is_array($key)){
				if(!$this->hasPostArray($key))
				return false;
			}else{
				if(!$this->hasPost($key))
				return false;
			}
		}
		return true;
	}

	/**
	 * Returns server and/or environment information
	 *
	 * @param string $key (optional)
	 * @throws Exception
	 * @return array|string
	 */
	public function getServer($key = null) {
		if(!isset($key)) {
			return $_SERVER;
		}

		if(isset($_SERVER[$key])) {
			return $_SERVER[$key];
		}
		throw new Exception('Server variable ' . $key . ' does not exist');
	}

	/**
	 * Checks for GET request
	 *
	 * @return boolean
	 */
	public function isGet() {
		return 'GET' == $this->getServer('REQUEST_METHOD');
	}

	/**
	 * Checks for POST request
	 *
	 * @return boolean
	 */
	public function isPost() {
		return 'POST' == $this->getServer('REQUEST_METHOD');
	}

	/**
	 * Checks for rqAjax in $_POST
	 *
	 * @return boolean
	 */
	public function isAjax(){
		return isset($_POST["rqAjax"]);
	}

	/**
	 * Fills $obj with data from $_POST.
	 *
	 * Uses the objects class_vars to set all values from $_POST. Set $exceptionOnNonSet to true if you want
	 * this function to throw an exception if any of the objects vars can't be set from $_POST
	 *
	 * @param mixed $obj
	 * @param boolean $exceptionOnNonSet
	 * @return mixed
	 */
	public function createFromPost($obj, $exceptionOnNonSet = false){
		foreach(get_class_vars(get_class($obj)) AS $var => $val)
		if($this->hasPost($var))
		$obj->{$var} = $this->getPost($var);
		elseif($exceptionOnNonSet)
		throw new Exception("Var {$var} is not set in _POST");

		return $obj;
	}

	/**
	 * Fills $obj with data from $_GET.
	 *
	 * Uses the objects class_vars to set all values from $_GET. Set $exceptionOnNonSet to true if you want
	 * this function to throw an exception if any of the objects vars can't be set from $_GET
	 *
	 * @param mixed $obj
	 * @param boolean $exceptionOnNonSet
	 * @return mixed
	 */
	public function createFromGet($obj, $exceptionOnNonSet = false){
		foreach(get_class_vars(get_class($obj)) AS $var => $val)
		if($this->hasParam($var))
		$obj->{$var} = $this->getParam($var);
		elseif($exceptionOnNonSet)
		throw new Exception("Var {$var} is not set in _POST");

		return $obj;
	}

	/**
	 * Sets action
	 *
	 * @param string $action
	 * @return Mvc_Request (fluent interface)
	 */
	public function setAction($action) {
		$this->_action = 'action' . ucfirst(strtolower($action));
		return $this;
	}

	/**
	 * Sets controller
	 *
	 * @param string $controller
	 * @return Mvc_Request (fluent interface)
	 */
	public function setController($controller, $path = null) {
		$lowercontroller = strtolower($controller);
		$controller = ucfirst($lowercontroller);

		if($path !== null){
			$list = glob($path . $this->_module . DIRECTORY_SEPARATOR . "*Controller.php");
			foreach($list as $file){
				$name = basename($file);
				$name = substr($name, 0, strpos($name, "Controller"));

				if(strtolower($name) == $lowercontroller){
					$controller = $name;
				}
			}
		}

		$this->_controller = ucfirst(strtolower($controller)) . 'Controller';

		return $this;
	}

	/**
	 * Sets module
	 *
	 * @param string $module
	 * @return Mvc_Request (fluent interface)
	 */
	public function setModule($module) {
		$this->_module = strtolower($module);
		return $this;
	}

	/**
	 * Sets parameter
	 *
	 * @param string $key
	 * @param string $value
	 * @return Mvc_Request (fluent interface)
	 */
	public function setParam($key, $value) {
		$this->_param[$key] = $value;
		return $this;
	}

}

/**
 *
 * @author daantimmer
 *
 * @package Library
 * @subpackage Mvc
 *
 */
class Post{
	private $vars;

	const NULL = null;
	const STR = "";
	const NUM = 0;
	const ERROR = -1;

	public function __construct(){
		$this->vars = $_POST;
	}

	public function __get($var){
		return $this->get($var);
	}

	public function get($var,$else = Post::ERROR){

		if(isset($this->$var))	return $this->vars[$var];
		if(Post::ERROR === $else) throw new Exception("Variable {$var} not set");
		return $else;
	}

	public function __set($var,$val){
		$this->vars[$var] = $val;
	}

	public function __isset($var){
		return isset($this->vars[$var]);
	}
}
